package org.ting.j20250110_gobang.game;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.ting.j20250110_gobang.J20250110GoBangApplication;
import org.ting.j20250110_gobang.model.User;
import org.ting.j20250110_gobang.service.UserService;

import java.io.IOException;
import java.util.UUID;
public class Room {
    private OnlineUserManager onlineUserManager;
    private ObjectMapper objectMapper;
    private RoomManager roomManager;
    private UserService userService;
    private String roomId;
    private User user1;
    private User user2;
    private int blackUser;
    private static int ROW = 15;
    private static int COL = 15;
    //棋盘， 0表示未落子，1表示玩家1的子，2表示玩家2的子
    private int[][] board = new int[ROW][COL];
    //处理落子请求
    public void putChess(GameRequest request) throws IOException {
        //1. 判断落子玩家
        int chess = request.getUserId() == user1.getUserId() ? 1 : 2;
        int row = request.getRow();
        int col = request.getCol();
        //2. 落子
        if(board[row][col] != 0) {
            System.out.println("[" + row + "," + col + "]已经有子了");
            return;
        }
        board[row][col] = chess;
        //3. 判断是否获胜
        int winnerId = checkWinner(row, col) ? request.getUserId() : -1;

        //4. 给房间中的玩家返回响应
        GameResponse response = new GameResponse();
        response.setMessage("putChess");
        response.setUserId(request.getUserId());
        response.setRow(row);
        response.setCol(col);
        response.setWinnerId(winnerId);
        //通过OnlineUserManager获取房间中的玩家
        WebSocketSession session1 = onlineUserManager.getFromRoom(user1.getUserId());
        WebSocketSession session2 = onlineUserManager.getFromRoom(user2.getUserId());
        //判断是否有玩家下线
        if(session1 == null) {
            //玩家1下线，玩家2获胜
            response.setWinnerId(user2.getUserId());
            System.out.println("玩家1掉线");
        }
        if(session1 == null) {
            //玩家2下线，玩家1获胜
            response.setWinnerId(user1.getUserId());
            System.out.println("玩家2掉线");
        }
        String resp = objectMapper.writeValueAsString(response);
        if(session1 != null) {
            session1.sendMessage(new TextMessage(resp));
        }
        if(session2 != null) {
            session2.sendMessage(new TextMessage(resp));
        }

        if(response.getWinnerId() != -1) {
            System.out.println("更新玩家信息");
            userService.userWin(response.getWinnerId());
            userService.userLose(response.getWinnerId() == user1.getUserId() ? user2.getUserId() : user1.getUserId());
            System.out.println("分出胜负， 游戏房间：" + roomId + "即将销毁");
            roomManager.remove(roomId, user1.getUserId(), user2.getUserId());
        }
    }

    public Room() {
        roomId = UUID.randomUUID().toString();
        onlineUserManager = J20250110GoBangApplication.context.getBean(OnlineUserManager.class);
        objectMapper = J20250110GoBangApplication.context.getBean(ObjectMapper.class);
        roomManager = J20250110GoBangApplication.context.getBean(RoomManager.class);
        userService = J20250110GoBangApplication.context.getBean(UserService.class);
    }
    private boolean checkWinner(int row, int col) {
        int count = 1;
        //判断行是否五子连珠
        for(int i = col + 1; i < COL; i++) {
            if(board[row][i] == board[row][col]) {
                count++;
            }else{
                break;
            }
        }
        for(int i = col - 1; i >= 0; i--) {
            if(board[row][i] == board[row][col]) {
                count++;
            }else{
                break;
            }
        }
        if(count >= 5) {
            return true;
        }

        //判断列是否五子连珠
        count = 1;
        for(int i = row + 1; i < ROW; i++) {
            if(board[i][col] == board[row][col]) {
                count++;
            }else{
                break;
            }
        }
        for(int i = row - 1; i >= 0; i--) {
            if(board[i][col] == board[row][col]) {
                count++;
            }else{
                break;
            }
        }
        if(count >= 5) {
            return true;
        }

        //判断左上到右下斜线是否五子连珠
        count = 1;
        for(int i = row + 1, j = col + 1; i < ROW && j < COL; i++, j++) {
            if(board[i][j] == board[row][col]) {
                count++;
            }else{
                break;
            }
        }
        for(int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
            if(board[i][j] == board[row][col]) {
                count++;
            }else{
                break;
            }
        }
        if(count >= 5) {
            return true;
        }

        //判断右上到左下斜线是否五子连珠
        count = 1;
        for(int i = row - 1, j = col + 1; i >= 0 && j < COL; i--, j++) {
            if(board[i][j] == board[row][col]) {
                count++;
            }else{
                break;
            }
        }
        for(int i = row + 1, j = col - 1; i < ROW && j >= 0; i++, j--) {
            if(board[i][j] == board[row][col]) {
                count++;
            }else{
                break;
            }
        }
        if(count >= 5) {
            return true;
        }

        return false;
    }

    public int getBlackUser() {
        return blackUser;
    }

    public void setBlackUser(int blackUser) {
        this.blackUser = blackUser;
    }


    public String getRoomId() {
        return roomId;
    }

    public void setRoomId(String roomId) {
        this.roomId = roomId;
    }

    public User getUser1() {
        return user1;
    }

    public void setUser1(User user1) {
        this.user1 = user1;
    }

    public User getUser2() {
        return user2;
    }

    public void setUser2(User user2) {
        this.user2 = user2;
    }
}
